import { Property, Player, GameState, PropertyType, GameError, GameErrorType } from '../types';

export class PropertyManager {
  /**
   * 购买地块
   */
  buyProperty(playerId: string, propertyId: string, gameState: GameState): boolean {
    const player = gameState.players.find(p => p.id === playerId);
    if (!player) {
      throw new GameError(GameErrorType.INVALID_MOVE, '玩家不存在');
    }

    const boardSpace = gameState.board.find(s => s.property?.id === propertyId);
    const property = boardSpace?.property;
    
    if (!property) {
      throw new GameError(GameErrorType.PROPERTY_NOT_AVAILABLE, '地块不存在');
    }

    if (property.owner !== null) {
      throw new GameError(GameErrorType.PROPERTY_NOT_AVAILABLE, '地块已被购买');
    }

    // 应用商业大亨的被动能力（10%折扣）
    let finalPrice = property.price;
    if (player.character.id === 'business-tycoon') {
      finalPrice = Math.floor(property.price * 0.9);
    }

    if (player.money < finalPrice) {
      throw new GameError(GameErrorType.INSUFFICIENT_FUNDS, '资金不足');
    }

    // 执行购买
    player.money -= finalPrice;
    property.owner = playerId;
    player.properties.push(propertyId);

    return true;
  }

  /**
   * 升级地块
   */
  upgradeProperty(propertyId: string, gameState: GameState): boolean {
    const boardSpace = gameState.board.find(s => s.property?.id === propertyId);
    const property = boardSpace?.property;
    
    if (!property) {
      throw new GameError(GameErrorType.PROPERTY_NOT_AVAILABLE, '地块不存在');
    }

    if (!property.owner) {
      throw new GameError(GameErrorType.PROPERTY_NOT_AVAILABLE, '地块无主');
    }

    const player = gameState.players.find(p => p.id === property.owner);
    if (!player) {
      throw new GameError(GameErrorType.INVALID_MOVE, '玩家不存在');
    }

    // 检查是否拥有整个颜色组
    if (!this.ownsColorGroup(player.id, property.colorGroup, gameState)) {
      throw new GameError(GameErrorType.INVALID_MOVE, '必须拥有整个颜色组才能升级');
    }

    // 检查是否已达到最高等级
    if (property.level >= property.rent.length - 1) {
      throw new GameError(GameErrorType.INVALID_MOVE, '已达到最高等级');
    }

    // 应用建筑师的被动能力（20%折扣）
    let upgradeCost = property.upgradeCost;
    if (player.character.id === 'architect') {
      upgradeCost = Math.floor(upgradeCost * 0.8);
    }

    if (player.money < upgradeCost) {
      throw new GameError(GameErrorType.INSUFFICIENT_FUNDS, '资金不足');
    }

    // 执行升级
    player.money -= upgradeCost;
    property.level += 1;

    return true;
  }

  /**
   * 计算租金
   */
  calculateRent(property: Property, gameState: GameState, diceRoll?: number): number {
    if (!property.owner || property.mortgaged) {
      return 0;
    }

    let rent = 0;

    if (property.type === PropertyType.STREET) {
      // 普通街道
      rent = property.rent[property.level] || 0;
      
      // 如果拥有整个颜色组但没有建筑，租金翻倍
      const owner = gameState.players.find(p => p.id === property.owner);
      if (owner && property.level === 0 && this.ownsColorGroup(owner.id, property.colorGroup, gameState)) {
        rent *= 2;
      }
    } else if (property.type === PropertyType.RAILROAD) {
      // 铁路：根据拥有的铁路数量
      const owner = gameState.players.find(p => p.id === property.owner);
      if (owner) {
        const railroadCount = gameState.board.filter(s => 
          s.property?.type === PropertyType.RAILROAD && 
          s.property.owner === owner.id
        ).length;
        rent = property.rent[railroadCount - 1] || 0;
      }
    } else if (property.type === PropertyType.UTILITY) {
      // 公用事业：根据骰子点数
      const owner = gameState.players.find(p => p.id === property.owner);
      if (owner && diceRoll) {
        const utilityCount = gameState.board.filter(s => 
          s.property?.type === PropertyType.UTILITY && 
          s.property.owner === owner.id
        ).length;
        const multiplier = utilityCount === 1 ? property.rent[0] : property.rent[1];
        rent = diceRoll * multiplier;
      }
    }

    return rent;
  }

  /**
   * 抵押地块
   */
  mortgageProperty(propertyId: string, gameState: GameState): void {
    const boardSpace = gameState.board.find(s => s.property?.id === propertyId);
    const property = boardSpace?.property;
    
    if (!property) {
      throw new GameError(GameErrorType.PROPERTY_NOT_AVAILABLE, '地块不存在');
    }

    if (property.mortgaged) {
      throw new GameError(GameErrorType.INVALID_MOVE, '地块已被抵押');
    }

    if (property.level > 0) {
      throw new GameError(GameErrorType.INVALID_MOVE, '必须先出售建筑物');
    }

    const player = gameState.players.find(p => p.id === property.owner);
    if (!player) {
      throw new GameError(GameErrorType.INVALID_MOVE, '玩家不存在');
    }

    // 抵押获得地块价格的50%
    const mortgageValue = Math.floor(property.price * 0.5);
    player.money += mortgageValue;
    property.mortgaged = true;
  }

  /**
   * 赎回地块
   */
  unmortgageProperty(propertyId: string, gameState: GameState): boolean {
    const boardSpace = gameState.board.find(s => s.property?.id === propertyId);
    const property = boardSpace?.property;
    
    if (!property) {
      throw new GameError(GameErrorType.PROPERTY_NOT_AVAILABLE, '地块不存在');
    }

    if (!property.mortgaged) {
      throw new GameError(GameErrorType.INVALID_MOVE, '地块未被抵押');
    }

    const player = gameState.players.find(p => p.id === property.owner);
    if (!player) {
      throw new GameError(GameErrorType.INVALID_MOVE, '玩家不存在');
    }

    // 赎回需要支付抵押价值的110%
    const unmortgageCost = Math.floor(property.price * 0.5 * 1.1);
    
    if (player.money < unmortgageCost) {
      throw new GameError(GameErrorType.INSUFFICIENT_FUNDS, '资金不足');
    }

    player.money -= unmortgageCost;
    property.mortgaged = false;

    return true;
  }

  /**
   * 检查是否拥有整个颜色组
   */
  ownsColorGroup(playerId: string, colorGroup: string, gameState: GameState): boolean {
    const propertiesInGroup = gameState.board.filter(s => 
      s.property?.colorGroup === colorGroup
    );

    if (propertiesInGroup.length === 0) {
      return false;
    }

    return propertiesInGroup.every(s => s.property?.owner === playerId);
  }

  /**
   * 支付租金
   */
  payRent(payerId: string, propertyId: string, gameState: GameState, diceRoll?: number): void {
    const payer = gameState.players.find(p => p.id === payerId);
    if (!payer) {
      throw new GameError(GameErrorType.INVALID_MOVE, '支付者不存在');
    }

    const boardSpace = gameState.board.find(s => s.property?.id === propertyId);
    const property = boardSpace?.property;
    
    if (!property || !property.owner) {
      return; // 无主地块不需要支付租金
    }

    if (property.owner === payerId) {
      return; // 自己的地块不需要支付租金
    }

    const owner = gameState.players.find(p => p.id === property.owner);
    if (!owner) {
      return;
    }

    // 检查是否有免租金卡
    const freeRentCardIndex = payer.items.findIndex(item => item.id === 'free-rent');
    if (freeRentCardIndex !== -1) {
      payer.items.splice(freeRentCardIndex, 1);
      return;
    }

    let rent = this.calculateRent(property, gameState, diceRoll);

    // 应用谈判专家的被动能力（15%折扣）
    if (payer.character.id === 'negotiator') {
      rent = Math.floor(rent * 0.85);
    }

    // 检查所有者是否有双倍收入卡
    const doubleRentCardIndex = owner.items.findIndex(item => item.id === 'double-rent');
    if (doubleRentCardIndex !== -1) {
      rent *= 2;
      owner.items.splice(doubleRentCardIndex, 1);
    }

    // 执行支付
    payer.money -= rent;
    owner.money += rent;
  }

  /**
   * 出售地块
   */
  sellProperty(propertyId: string, gameState: GameState): void {
    const boardSpace = gameState.board.find(s => s.property?.id === propertyId);
    const property = boardSpace?.property;
    
    if (!property) {
      throw new GameError(GameErrorType.PROPERTY_NOT_AVAILABLE, '地块不存在');
    }

    const player = gameState.players.find(p => p.id === property.owner);
    if (!player) {
      throw new GameError(GameErrorType.INVALID_MOVE, '玩家不存在');
    }

    // 出售获得地块价格的50% + 建筑价值的50%
    let sellValue = Math.floor(property.price * 0.5);
    sellValue += Math.floor(property.upgradeCost * property.level * 0.5);

    player.money += sellValue;
    
    // 移除地块
    const propertyIndex = player.properties.indexOf(propertyId);
    if (propertyIndex !== -1) {
      player.properties.splice(propertyIndex, 1);
    }
    
    property.owner = null;
    property.level = 0;
    property.mortgaged = false;
  }
}

// 导出单例实例
export const propertyManager = new PropertyManager();
